/*
 * lifegame.c
 *
 *  Created on: 2020.6.1
 *      Author: longhe
 */

#include <stdlib.h>
#include <time.h>
#include "lifegame.h"

LifeGame_T lg_new(unsigned char width, unsigned char height, unsigned char rate){
	LifeGame_T lg = {width, height, 0x01 ,NULL};
	lg.data=(char **)malloc(lg.w*sizeof(char *));
	unsigned char i=0;
	srand((unsigned)time(0));
	for(i=0; i<lg.w; i++){
		lg.data[i]=(char *)malloc(lg.h*sizeof(char));
		unsigned char j=0;
		for(j=0; j<lg.h; j++){
			lg.data[i][j]=(rand() % 100)<rate? 1:0;
		}
	}
	return lg;
}

void lg_evolution(LifeGame_T *lg){
	char old_bit =  lg->bit;
	char new_bit =  old_bit^0x03;
	unsigned char i,j;
	for(j=0; j<lg->h; j++){
			for(i=0; i<lg->w; i++){
			 unsigned char ai = i==0? 0:i-1;
			 unsigned char aj = j==0? 0:j-1;
			 unsigned char bi = i<(lg->w-1)? i+1:i;
			 unsigned char bj = j<(lg->h-1)? j+1:j;
			 char cnt=0;
			 unsigned char ii,jj;
			 for(ii=ai;ii<=bi;ii++){
				 for(jj=aj;jj<=bj;jj++){
					 if(ii==i && jj==j) continue;
					 char live = lg->data[ii][jj]&old_bit;
					 if(live) cnt++;
				 }
			 }
			 if(cnt==2){
				 // keep
				 if( lg->data[i][j]&old_bit){
					 //live -> live
					 lg->data[i][j] |= new_bit;
				 }else{
					 // die -> die
					 lg->data[i][j] &= ~new_bit;
				 }
			 }else if(cnt==3){
				 // any -> live
				 lg->data[i][j] |= new_bit;
			 }else{
				 // any -> die
				 lg->data[i][j] &= ~new_bit;
			 }
		}
	}
	lg->bit=new_bit;
}

char lg_live(LifeGame_T *lg, unsigned char i, unsigned char j){
	return lg->data[i][j] & lg->bit;
}

void lg_clean(LifeGame_T *lg){
	if(lg->data!=NULL){
		unsigned char i=0;
		for(i=0; i<lg->w; i++){
			free(lg->data[i]);
		}
		free(lg->data);
		lg->data=NULL;
	}
}
